/*********************************************************************************
 *      Copyright:  (C) 2022 Zhang Changxing<ZhangChangxingVIP@163.com>
 *                  All rights reserved.
 *
 *       Filename:  main.c
 *    Description:  This file is used to connect to the platform client.
 *                 
 *        Version:  1.0.0(05/1/2022)
 *         Author:  Zhang Changxing <ZhangChangxingVIP@163.com>
 *      ChangeLog:  1, Release initial version on "05/1/2022  01:33:25 AM"
 *                 
 ********************************************************************************/

#include "main.h"

static inline void print_usage(char *programe);

int main(int argc, char *argv[])
{
    int         rv = -1;
    iotd_ctx_t  iotd_ctx;
    float       temp;
    pack_info_t pack_info;
    int         latest_time = 0;
    int         last_time = 0;
    char        datime[128];
    int         ch;
    int         daemon_run = 0;
    int         interval = 8;
    char        devid_buf[DEVID_LEN];//Storage Device Name
    int         sn = 1;//The default SN is set to 1
    int         platform;
    int         start_time;
    signal_global_run = 1;

    //mqtt_connect_ctx_t *mqtt_connect_ctx = &(iotd_ctx.mqtt_connect_ctx);
    pub_ctx_t   *pub_ctx = &(iotd_ctx.pub_ctx);
    log_ctx_t   *log_ctx = &(iotd_ctx.log_ctx);

    struct option opts[] = {
        {"Ali", no_argument, NULL, 'a'},
        {"Huawei", no_argument, NULL, 'w'},
        {"Tencent", no_argument, NULL, 'x'},
        {"interval time", required_argument, NULL, 't'},
        {"daemon", no_argument, NULL, 'b'},
        {"SN", required_argument, NULL, 's'},
        {"stdout", no_argument, NULL, 'd'},
        {"help", no_argument, NULL, 'h'},
        {0, 0, 0, 0}
    };

    memset(&iotd_ctx,0,sizeof(iotd_ctx));

    while ((ch = getopt_long(argc, argv, "awxt:bs:dh", opts, NULL)) != -1)
    {
        switch (ch)
        {
            case 'a':
            {
                platform = ALI;
                break;
            }
            case 'x':
            {
                platform = TENGCENT;
                break;
            }
            case 'w':
            {
                platform = HUAWEI;
                break;
            }
            case 'b':
            {
                daemon_run =1;
                break;
            }
            case 't':
            {
                interval = atoi(optarg);
            }
            case 's':
            {
                sn = atoi(optarg);
                break;
            }
            case 'd':
            {
                strncpy(log_ctx->logfile, "stdout", strlen("stdout"));//Output log information to standard output
                break;
            }
            case 'h':
            {
                print_usage(argv[0]);
                return 0;
            }
            default:
            {
                printf("%s input invalid argument!\n", __func__);
                return -1;
            }
        }
    }

    rv = inifile_parsing(&iotd_ctx, platform);
    if (rv)
    {
        fprintf(stderr, "Execute ini_parsing failure!\n");
        return -2;
    }

    if( logger_init(log_ctx->logfile, log_ctx->loglevel) < 0)
    {
        fprintf(stderr, "initial logger system failure\n");
        return -3;
    }

	log_info("\n\n\n");
	log_info("*************************************************************************");
	log_info("*                     The client starts running                         *");
	log_info("*************************************************************************\n");


    if(daemon_run)
    {
        daemon(1,1);
    }

    install_signal();

    if(sqlite_init())
    {
        return -4;
    }
    log_info("sqlite_init sucessfully!\n");

    
    mqtt_init(&iotd_ctx);

    last_time = 0;
    while (signal_global_run)
    {   
        sleep(2);
        check_and_rollback(log_ctx->logfile, log_ctx->logsize);
        latest_time = getime(NULL);

        #if 1
        log_info("latest_time - last_time:%d\n", latest_time - last_time);
        if((latest_time - last_time) >= interval)
        {
            log_info("*****************************   The temperature sampling  ******************************\n");
            #if 0
            if(temperature(&temp))
            {
                log_error("Failed to obtain the temperature!\n");
                return -2;
            }
            #endif
            temp =temp + 1;
            last_time = getime(datime);
            
            memset(&pack_info, 0, sizeof(pack_info));
            snprintf(pack_info.devid, DEVID_LEN, "RPI%04d", sn);
            strncpy(pack_info.strtime, datime, strlen(datime));
            pack_info.temper = temp;
            
            pack_to_cjson(pub_ctx, pack_info);

            if(0 == pub_ctx->connect_flag)
            {
                db_data_insert(pack_info);
                continue;
            }

            pub_ctx->pub_flag = 0;
            rv = publish_data(pub_ctx);
            start_time = getime(NULL);
            do{

            }while((pub_ctx->pub_flag == 0) && ((getime(NULL) - start_time) < 2));
            if(( rv < 0) || (pub_ctx->pub_flag == 0))
            {
                pub_ctx->connect_flag = 0;
                db_data_insert(pack_info);
            }
            else
            {
                log_info("Publish sample data sucessfully:temperature= %f\n", pack_info.temper);
            }
            //log_info("pub_ctx->connect_flag:%d\n", pub_ctx->connect_flag);
        }
        
        if(check_table_data() && (1 == pub_ctx->connect_flag))
        {
            log_info("*****************************   Sending database data  ******************************\n");
            select_first_data(&pack_info);
            pack_to_cjson(pub_ctx, pack_info);
            
            pub_ctx->pub_flag = 0;
            rv = publish_data(pub_ctx);
            start_time = getime(NULL);
            do{

            }while((pub_ctx->pub_flag == 0) && ((getime(NULL) - start_time) < 2));

            if( (rv < 0) || (pub_ctx->pub_flag == 0))
            {
                pub_ctx->connect_flag = 0;
                continue;
            }

            db_data_delete();
            log_info("Publish database data sucessfully:temperature= %f\n", pack_info.temper);
        }
        #endif  
    }
    
    close_database();
    mosquitto_cleanup();
    return 0;
}

static inline void print_usage(char *programe)
{
    printf("Usage:%s[OPTION]\n\n",programe);
    printf("-a[Ali]:Select Ali Cloud service agent!\n");
    printf("-h[Huawei]:Select Huawei Cloud service agent!\n");
    printf("-c[Tencent]:Select Tencent Cloud service agent!\n");
    printf("-t[time]:Interval time!\n");
    printf("\n%s - a -t 30\n", programe);
}